﻿

// 头文件包含部分
#include "context.h" // 包含上下文类的定义
#include <market_api.h> // 包含市场 API 的定义
#include <trader_api.h> // 包含交易 API 的定义
#include <interface.h> // 包含接口的定义
#include <params.hpp> // 包含参数处理类的定义
#include <time_utils.hpp> // 包含时间工具的定义
#include <process_helper.hpp> // 包含进程处理的定义

// context 类的构造函数
context::context()noexcept :
	_is_runing(false), // 运行状态
	_realtime_thread(nullptr), // 实时线程
	_max_position(10000), // 最大持仓量
	_tick_callback(nullptr), // Tick 数据回调函数
	_last_order_time(0), // 上一个订单时间
	_bind_cpu_core(-1), // 绑定的 CPU 核心
	_loop_interval(1), // 循环间隔时间（秒）
	_init_callback(nullptr), // 初始化回调函数
	_update_callback(nullptr), // 更新回调函数
	_destroy_callback(nullptr), // 销毁回调函数
	_last_tick_time(0), // 上一个 Tick 时间
	realtime_event() // 实时事件处理对象
{
}

// context 类的析构函数
context::~context()noexcept
{
}

// 初始化函数
void context::init(const params& control_config, const params& include_config, bool reset_trading_day)noexcept
{
	_max_position = control_config.get<uint32_t>("position_limit"); // 设置最大持仓量
	_bind_cpu_core = control_config.get<int16_t>("bind_cpu_core"); // 设置绑定的 CPU 核心
	_loop_interval = control_config.get<uint32_t>("loop_interval"); // 设置循环间隔时间
	_thread_priority = control_config.get<int16_t>("thread_priority"); // 设置线程优先级
	_include_config = include_config.data(); // 设置包含的配置数据
	auto section_config = include_config.get<std::string>("section_config"); // 获取交易时间段配置
	_section_config = std::make_shared<trading_section>(section_config); // 创建交易时间段对象
	int16_t process_priority = control_config.get<int16_t>("process_priority"); // 获取进程优先级
	if (static_cast<int16_t>(PriorityLevel::LowPriority) <= process_priority && process_priority <= static_cast<int16_t>(PriorityLevel::RealtimePriority))
	{
		PriorityLevel level = static_cast<PriorityLevel>(process_priority); // 将优先级转换为 PriorityLevel 枚举值
		if (!process_helper::set_priority(level)) // 设置进程优先级
		{
			LOG_WARNING("set_priority failed"); // 设置失败时记录警告日志
		}
	}
}

// 加载交易数据
void context::load_trader_data()noexcept
{
	LOG_INFO("context load trader data"); // 记录日志，开始加载交易数据
	auto trader_data = get_trader().get_trader_data(); // 获取交易数据
	if (trader_data)
	{
		_position_info.clear(); // 清除持仓信息
		_order_info.clear(); // 清除订单信息
		for (const auto& it : trader_data->orders)
		{
			auto& pos = _position_info[it.code]; // 获取持仓信息
			pos.id = it.code; // 设置持仓 ID
			if (it.offset == offset_type::OT_OPEN) // 判断是否为开仓订单
			{
				if (it.direction == direction_type::DT_LONG) // 判断方向是否为多头
				{
					pos.long_pending += it.total_volume; // 更新多头待处理量
				}
				else if (it.direction == direction_type::DT_SHORT) // 判断方向是否为空头
				{
					pos.short_pending += it.total_volume; // 更新空头待处理量
				}
			}
			else if (it.offset == offset_type::OT_CLSTD) // 判断是否为平仓订单
			{
				if (it.direction == direction_type::DT_LONG) // 判断方向是否为多头
				{
					pos.today_long.frozen += it.total_volume; // 更新今日多头冻结量
				}
				else if (it.direction == direction_type::DT_SHORT) // 判断方向是否为空头
				{
					pos.today_short.frozen += it.total_volume; // 更新今日空头冻结量
				}
			}
			else // 其他订单类型（通常为历史订单）
			{
				if (it.direction == direction_type::DT_LONG) // 判断方向是否为多头
				{
					pos.history_long.frozen += it.total_volume; // 更新历史多头冻结量
				}
				else if (it.direction == direction_type::DT_SHORT) // 判断方向是否为空头
				{
					pos.history_short.frozen += it.total_volume; // 更新历史空头冻结量
				}
			}
			_order_info[it.estid] = it; // 存储订单信息
		}
		
		for (const auto& it : trader_data->positions)
		{
			auto& pos = _position_info[it.id]; // 获取持仓信息
			pos.id = it.id; // 设置持仓 ID
			pos.today_long.postion = it.today_long; // 更新今日多头持仓量
			pos.today_short.postion = it.today_short; // 更新今日空头持仓量
			pos.history_long.postion = it.history_long; // 更新历史多头持仓量
			pos.history_short.postion = it.history_short; // 更新历史空头持仓量
		}
	}
}

// 启动服务
bool context::start_service()noexcept
{
	if (_is_runing) // 判断服务是否已经在运行
	{
		return false; // 如果已经在运行，返回 false
	}
	_is_runing = true; // 设置服务为运行状态
	load_trader_data(); // 加载交易数据
	get_trader().bind_event(trader_event_type::TET_OrderCancel, std::bind(&context::handle_cancel, this, std::placeholders::_1)); // 绑定订单撤销事件处理
	get_trader().bind_event(trader_event_type::TET_OrderPlace, std::bind(&context::handle_entrust, this, std::placeholders::_1)); // 绑定订单委托事件处理
	get_trader().bind_event(trader_event_type::TET_OrderDeal, std::bind(&context::handle_deal, this, std::placeholders::_1)); // 绑定订单成交事件处理
	get_trader().bind_event(trader_event_type::TET_OrderTrade, std::bind(&context::handle_trade, this, std::placeholders::_1)); // 绑定订单交易事件处理
	get_trader().bind_event(trader_event_type::TET_OrderError, std::bind(&context::handle_error, this, std::placeholders::_1)); // 绑定订单错误事件处理
	get_market().bind_event(market_event_type::MET_TickReceived, std::bind(&context::handle_tick, this, std::placeholders::_1)); // 绑定市场 Tick 数据事件处理

	// 启动实时处理线程
	_realtime_thread = new std::thread([this]()->void{
		if (0 <= _bind_cpu_core && _bind_cpu_core < static_cast<int16_t>(std::thread::hardware_concurrency()))
		{
			if (!process_helper::thread_bind_core(static_cast<uint32_t>(_bind_cpu_core))) // 绑定线程到指定 CPU 核心
			{
				LOG_WARNING("bind to core failed :", _bind_cpu_core); // 绑定失败时记录警告日志
			}
		}
		if (static_cast<int16_t>(PriorityLevel::LowPriority) <= _thread_priority && _thread_priority <= static_cast<int16_t>(PriorityLevel::RealtimePriority))
		{
			PriorityLevel level = static_cast<PriorityLevel>(_thread_priority); // 将线程优先级转换为 PriorityLevel 枚举值
			if (!process_helper::set_thread_priority(level)) // 设置线程优先级
			{
				LOG_WARNING("set_thread_priority failed"); // 设置失败时记录警告日志
			}
		}
		auto last_time = time_utils::get_current_time(); // 获取当前时间
		while (_is_runing) // 当服务运行时
		{
			auto now = time_utils::get_current_time(); // 获取当前时间
			if ((now - last_time) > _loop_interval) // 判断是否超过循环间隔时间
			{
				_update_callback(); // 执行更新回调函数
				last_time = now; // 更新上次时间
			}
			realtime_event::process(); // 处理实时事件
		}
	});

	if (_init_callback)
	{
		_init_callback(); // 执行初始化回调函数
	}
	return true; // 启动成功，返回 true
}

// 停止服务
void context::stop_service()noexcept
{
	if (!_is_runing) // 判断服务是否未运行
	{
		return; // 如果未运行，直接返回
	}
	_is_runing = false; // 设置服务为停止状态
	if (_realtime_thread)
	{
		_realtime_thread->join(); // 等待实时线程结束
		delete _realtime_thread; // 删除实时线程对象
		_realtime_thread = nullptr; // 设置线程对象为 nullptr
	}
	realtime_event::clear(); // 清除实时事件
	if (_destroy_callback)
	{
		_destroy_callback(); // 执行销毁回调函数
	}
}

// 创建订单
void context::place_order(const std::string& code, int32_t volume, order_action action, order_offset offset, order_direction direction)noexcept
{
	if (_position_info.find(code) == _position_info.end()) // 判断持仓信息是否存在
	{
		LOG_WARNING("not find pos of code ", code); // 如果不存在，记录警告日志
		return;
	}
	auto& pos = _position_info[code]; // 获取持仓信息
	if (order_action::OA_Unknown == action) // 判断订单动作是否未知
	{
		LOG_WARNING("unknown order action"); // 如果未知，记录警告日志
		return;
	}
	if (order_offset::OO_Unknown == offset) // 判断订单开平仓类型是否未知
	{
		LOG_WARNING("unknown order offset"); // 如果未知，记录警告日志
		return;
	}
	if (order_direction::OD_Unknown == direction) // 判断订单方向是否未知
	{
		LOG_WARNING("unknown order direction"); // 如果未知，记录警告日志
		return;
	}
	if (volume <= 0) // 判断订单量是否小于等于零
	{
		LOG_WARNING("order volume less than 0"); // 如果小于零，记录警告日志
		return;
	}
	if (volume > _max_position) // 判断订单量是否大于最大持仓量
	{
		LOG_WARNING("order volume exceed max position ", _max_position); // 如果超过最大持仓量，记录警告日志
		return;
	}
	if (_last_order_time && (time_utils::get_current_time() - _last_order_time < 1000)) // 判断是否在上次订单时间之后不到 1 秒
	{
		LOG_WARNING("order interval less than 1 second"); // 如果是，记录警告日志
		return;
	}
	auto order_id = get_trader().place_order(code, volume, action, offset, direction); // 创建订单
	if (order_id)
	{
		LOG_INFO("place order ", code, " ", volume, " ", action, " ", offset, " ", direction, " ", order_id); // 记录订单创建日志
		_last_order_time = time_utils::get_current_time(); // 更新上次订单时间
	}
	else
	{
		LOG_WARNING("place order failed "); // 订单创建失败时记录警告日志
	}
}

// 取消订单
void context::cancel_order(uint32_t order_id)noexcept
{
	if (!_order_info.count(order_id)) // 判断订单是否存在
	{
		LOG_WARNING("not find order id ", order_id); // 如果不存在，记录警告日志
		return;
	}
	get_trader().cancel_order(order_id); // 取消订单
	LOG_INFO("cancel order id ", order_id); // 记录订单取消日志
}

// 处理订单撤销事件
void context::handle_cancel(const order_info& info)noexcept
{
	LOG_INFO("handle cancel order id ", info.estid); // 记录订单撤销日志
	auto it = _order_info.find(info.estid); // 查找订单信息
	if (it != _order_info.end())
	{
		_order_info.erase(it); // 移除订单信息
	}
	auto& pos = _position_info[info.code]; // 获取持仓信息
	if (info.direction == direction_type::DT_LONG) // 判断订单方向是否为多头
	{
		if (info.offset == offset_type::OT_OPEN) // 判断订单类型是否为开仓
		{
			pos.long_pending -= info.total_volume; // 更新多头待处理量
		}
		else if (info.offset == offset_type::OT_CLSTD) // 判断订单类型是否为平仓
		{
			pos.today_long.frozen -= info.total_volume; // 更新今日多头冻结量
		}
		else // 其他订单类型
		{
			pos.history_long.frozen -= info.total_volume; // 更新历史多头冻结量
		}
	}
	else if (info.direction == direction_type::DT_SHORT) // 判断订单方向是否为空头
	{
		if (info.offset == offset_type::OT_OPEN) // 判断订单类型是否为开仓
		{
			pos.short_pending -= info.total_volume; // 更新空头待处理量
		}
		else if (info.offset == offset_type::OT_CLSTD) // 判断订单类型是否为平仓
		{
			pos.today_short.frozen -= info.total_volume; // 更新今日空头冻结量
		}
		else // 其他订单类型
		{
			pos.history_short.frozen -= info.total_volume; // 更新历史空头冻结量
		}
	}
}

// 处理订单委托事件
void context::handle_entrust(const order_info& info)noexcept
{
	LOG_INFO("handle entrust order id ", info.estid); // 记录订单委托日志
	auto& pos = _position_info[info.code]; // 获取持仓信息
	if (info.direction == direction_type::DT_LONG) // 判断订单方向是否为多头
	{
		if (info.offset == offset_type::OT_OPEN) // 判断订单类型是否为开仓
		{
			pos.long_pending += info.total_volume; // 更新多头待处理量
		}
		else if (info.offset == offset_type::OT_CLSTD) // 判断订单类型是否为平仓
		{
			pos.today_long.frozen += info.total_volume; // 更新今日多头冻结量
		}
		else // 其他订单类型
		{
			pos.history_long.frozen += info.total_volume; // 更新历史多头冻结量
		}
	}
	else if (info.direction == direction_type::DT_SHORT) // 判断订单方向是否为空头
	{
		if (info.offset == offset_type::OT_OPEN) // 判断订单类型是否为开仓
		{
			pos.short_pending += info.total_volume; // 更新空头待处理量
		}
		else if (info.offset == offset_type::OT_CLSTD) // 判断订单类型是否为平仓
		{
			pos.today_short.frozen += info.total_volume; // 更新今日空头冻结量
		}
		else // 其他订单类型
		{
			pos.history_short.frozen += info.total_volume; // 更新历史空头冻结量
		}
	}
}

// 处理订单成交事件
void context::handle_deal(const order_info& info)noexcept
{
	LOG_INFO("handle deal order id ", info.estid); // 记录订单成交日志
	auto& pos = _position_info[info.code]; // 获取持仓信息
	if (info.direction == direction_type::DT_LONG) // 判断订单方向是否为多头
	{
		if (info.offset == offset_type::OT_OPEN) // 判断订单类型是否为开仓
		{
			pos.today_long.postion += info.total_volume; // 更新今日多头持仓量
			pos.long_pending -= info.total_volume; // 更新多头待处理量
		}
		else if (info.offset == offset_type::OT_CLSTD) // 判断订单类型是否为平仓
		{
			pos.today_long.frozen -= info.total_volume; // 更新今日多头冻结量
		}
		else // 其他订单类型
		{
			pos.history_long.frozen -= info.total_volume; // 更新历史多头冻结量
		}
	}
	else if (info.direction == direction_type::DT_SHORT) // 判断订单方向是否为空头
	{
		if (info.offset == offset_type::OT_OPEN) // 判断订单类型是否为开仓
		{
			pos.today_short.postion += info.total_volume; // 更新今日空头持仓量
			pos.short_pending -= info.total_volume; // 更新空头待处理量
		}
		else if (info.offset == offset_type::OT_CLSTD) // 判断订单类型是否为平仓
		{
			pos.today_short.frozen -= info.total_volume; // 更新今日空头冻结量
		}
		else // 其他订单类型
		{
			pos.history_short.frozen -= info.total_volume; // 更新历史空头冻结量
		}
	}
}

// 处理订单交易事件
void context::handle_trade(const order_info& info)noexcept
{
	LOG_INFO("handle trade order id ", info.estid); // 记录订单交易日志
}

// 处理订单错误事件
void context::handle_error(const order_info& info)noexcept
{
	LOG_ERROR("handle error order id ", info.estid); // 记录订单错误日志
}

// 处理 Tick 数据
void context::handle_tick(const tick_info& info)noexcept
{
	LOG_INFO("handle tick code ", info.code, " last price ", info.last_price); // 记录 Tick 数据日志
}

